#include "uart.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

uart_s debug_uart = {0};

uint8_t debug_rx_buff[DEBUG_RX_SIZE];
uint8_t debug_tx_buff[DEBUG_TX_SIZE];

void debug_uart_init(void){
	
	debug_uart.RxInPtr = &debug_uart.RxLocation[0];
	debug_uart.RxOutPtr = &debug_uart.RxLocation[0];
	debug_uart.RxEndPtr = &debug_uart.RxLocation[DEBUG_RX_COUNT - 1];
	debug_uart.RxCounter = 0;
	debug_uart.RxInPtr->start = debug_rx_buff;
	
	debug_uart.TxInPtr = &debug_uart.TxLocation[0];
	debug_uart.TxOutPtr = &debug_uart.TxLocation[0];
	debug_uart.TxEndPtr = &debug_uart.TxLocation[DEBUG_TX_COUNT - 1];
	debug_uart.TxCounter = 0;
	debug_uart.TxInPtr->start = debug_tx_buff;	
	
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart1,debug_uart.RxInPtr->start,DEBUG_RX_MAX);
}

void debug_printf(char *format,...){
	va_list listdata;
	va_start(listdata,format);
	uint16_t count = vsprintf((char *)debug_tx_buff,format,listdata);
	va_end(listdata);
	HAL_UART_Transmit(&huart1,debug_tx_buff,count,0xaa);
}

bool debug_uart_rx_data(uint8_t *data,uint16_t *datalen){
	if(debug_uart.RxOutPtr != debug_uart.RxInPtr){
		*datalen = debug_uart.RxOutPtr->end - debug_uart.RxOutPtr->start + 1;
		memcpy(data,debug_uart.RxOutPtr->start,debug_uart.RxOutPtr->end - debug_uart.RxOutPtr->start + 1);
		debug_uart.RxOutPtr++;
		if(debug_uart.RxOutPtr == debug_uart.RxEndPtr){
			debug_uart.RxOutPtr = &debug_uart.RxLocation[0];
		}
		return true;
	}else{
		return false;
	}
}

void debug_uart_tx_data_loop(void){
	if((debug_uart.TxOutPtr != debug_uart.TxInPtr)&&(debug_uart.TxState==0)){
		debug_uart.TxState = 1;
		HAL_UART_Transmit_DMA(&huart1,debug_uart.TxOutPtr->start,debug_uart.TxOutPtr->end - debug_uart.TxOutPtr->start + 1);
		debug_uart.TxOutPtr++;
		if(debug_uart.TxOutPtr == debug_uart.TxEndPtr){
			debug_uart.TxOutPtr = &debug_uart.TxLocation[0];
		}
	}
}

void debug_uart_tx_data(uint8_t *data,uint32_t datalen){
	if((DEBUG_TX_SIZE - debug_uart.TxCounter) >= datalen){
		debug_uart.TxInPtr->start = &debug_tx_buff[debug_uart.TxCounter];
	}else{
		debug_uart.TxCounter = 0;
		debug_uart.TxInPtr->start = debug_tx_buff;
	}
	memcpy(debug_uart.TxInPtr->start,data,datalen);
	debug_uart.TxCounter += datalen;
	debug_uart.TxInPtr->end = &debug_tx_buff[debug_uart.TxCounter - 1];
	debug_uart.TxInPtr++;
	if(debug_uart.TxInPtr == debug_uart.TxEndPtr){
		debug_uart.TxInPtr = &debug_uart.TxLocation[0];
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	if(huart->Instance == USART1){

	}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){
	if(huart->Instance == USART1){

	}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){	
	if(huart->Instance == USART1){
		debug_uart.TxState = 0;
	}
}
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart){
	if(huart->Instance == USART1){
		debug_uart.RxInPtr->end = &debug_rx_buff[debug_uart.RxCounter - 1];
		debug_uart.RxInPtr++;
		if(debug_uart.RxInPtr == debug_uart.RxEndPtr){
			debug_uart.RxInPtr = &debug_uart.RxLocation[0];
		}
		if((DEBUG_RX_SIZE - debug_uart.RxCounter) < DEBUG_RX_MAX){
			debug_uart.RxCounter = 0;
			debug_uart.RxInPtr->start = debug_rx_buff;
		}else{
			debug_uart.RxInPtr->start = &debug_rx_buff[debug_uart.RxCounter];
		}
		HAL_UART_Receive_DMA(&huart1,debug_uart.RxInPtr->start,DEBUG_RX_MAX);
	}
}
